package com.google.code.irouter.plugin.salesman;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.Validate;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.InputTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.SimpleNodeIterator;

import weibo4j.Status;
import weibo4j.Weibo;
import weibo4j.http.AccessToken;
import weibo4j.http.PostParameter;
import weibo4j.http.RequestToken;

import com.google.code.irouter.model.Human;
import com.google.code.irouter.model.Product;
import com.google.code.irouter.utils.CacheUtil;
import com.google.code.irouter.utils.TextUtil;

public final class Sina implements Serializable {

	private static final long serialVersionUID = -3661985859934095572L;

	private static final Logger log = Logger.getLogger(Sina.class.getName());
	
	private static Weibo weibo;
	private static RequestToken requestToken;
	private static String token;
	private static String tokenSecret;
	
	public boolean doFollow(Product product, Human human) {
		boolean result = true;
		try {
		weibo.createFriendshipByUserid(human.getId());
		} catch (Exception e) {
			if(e.getMessage().indexOf("40303") < 0) {
				log.severe(e.getMessage());
				result = false;
			}
		}
		return result;
	}
	
	public boolean doComment(Product product, Human human) {
		boolean result = true;
		try {
		List<Status> statuss = weibo.getUserTimeline(human.getId());
		if(statuss.size() == 0)
			return result;
		
		weibo.updateComment(product.getDescription(), String.valueOf(statuss.get(0).getId()), null);
		} catch (Exception e) {
			log.severe(e.getMessage());
			result = false;
		}
		return result;
	}

	public boolean follow(Product product, Human human) {
		boolean result = true;
		try {
		check(product).doFollow(product, human);
		} catch (Exception e) {
			if(e.getMessage().indexOf("40303") < 0) {
				log.severe(e.getMessage());
				result = false;
			}
		}
		return result;
	}
	
	public boolean comment(Product product, Human human) {
		boolean result = true;
		try {
		auth(product);
		check(product).doComment(product, human);
		} catch (Exception e) {
			log.severe(e.getMessage());
			result = false;
		}
		return result;
	}
	
	private Sina check(Product product) throws Exception {
		Sina result = this;
		if (CacheUtil.containsKey(getKey(product))) {
			result = (Sina) CacheUtil.get(getKey(product));
		} else {
			if (auth(product)) {
				save(product);
			}
		}
		return result;
	}
	
	private void save(Product product) {
		CacheUtil.put(getKey(product), this);
	}

	private String getKey(Product product) {
		return TextUtil.contact(
					true, 
					this.getClass().getName(),
					product.getConsumer(), 
					product.getSecret(),
					product.getUser()
				);
	}
	
	private boolean auth(Product product) throws Exception {
		System.setProperty("weibo4j.oauth.consumerKey", product.getConsumer());
		System.setProperty("weibo4j.oauth.consumerSecret", product.getSecret());
		weibo = new Weibo();
		boolean result = true;
    	requestToken = weibo.getOAuthRequestToken();
    	Parser parser = new Parser();
    	String url = requestToken.getAuthorizationURL();
    	parser.setURL(url);
		parser.setEncoding(parser.getEncoding());		
		NodeList nodeList = parser.parse(new NodeClassFilter(InputTag.class));		
		SimpleNodeIterator simpleNodeIterator = nodeList.elements();
		List<PostParameter> postParameterList = new ArrayList<PostParameter>();
		while (simpleNodeIterator.hasMoreNodes()) {
			Node node = simpleNodeIterator.nextNode();
			InputTag inputnode = (InputTag) node;
			String name = inputnode.getAttribute("name");
			String value = inputnode.getAttribute("value");
			if (name.equals("userId"))
				value = product.getUser();
			else if (name.equals("passwd"))
				value = product.getPassword();
			try {
				Validate.notNull(value);
				PostParameter pp = new PostParameter(name, value);
				postParameterList.add(pp);
			} catch (IllegalArgumentException e) {
			}			
		}		
		PostParameter[] postParameters = postParameterList.toArray(new PostParameter[0]);
		String response = requestToken.getHttpClient().post(url, postParameters).asString();
		Pattern pattern = Pattern.compile("<span class=\"fb\">.*</span>");
		Matcher matcher = pattern.matcher(response);
		String pin = "";
		while (matcher.find())
		{  
		   pin = response.substring(matcher.start(), matcher.end()).replace("<span class=\"fb\">", "").replace("</span>", "");
		   break;
		}
		try {
			Validate.notEmpty(pin);
			AccessToken accessToken = requestToken.getAccessToken(pin);
			token = accessToken.getToken();
			tokenSecret = accessToken.getTokenSecret();
			weibo.setToken(token, tokenSecret);
			
		} catch (IllegalArgumentException e) {
			log.severe(e.getMessage());
			result = false;
		}
		return result;
	}
}
